import { useState, useRef, useCallback, ComponentProps, useEffect } from 'react';
import { Select, Spin, Avatar, SelectProps, InputTag, Typography, Space } from '@arco-design/web-react';
import { TagWithWeight } from './TagWithWeight';
import { debounce, eq } from 'lodash-es';
import { SelectHandle } from '@arco-design/web-react/es/Select/select';
import './index.css';
import { useTRPCClient } from '@server/trpc/client';
import { Tag } from '@server/routers/image';

type IProps = {
  value?: string
  onChange?: (value: string) => void;
}

// 解析value获取原始文本和权重
const parseValue = (val: string) => {
  const match = val.match(/\(([^:]+):\s*([\d.]+)\)/);

  if (!match) {
    return {
      text: val,
      weight: 1,
    }
  }
  return {
    text: match?.[1] || val,
    weight: match?.[2] ? parseFloat(match[2]) : 1
  };
};

function PromptTagInput({ value, onChange}: IProps) {
  const [options, setOptions] = useState<ComponentProps<typeof Select>['options']>([]);
  const [internalValue, setInternalValue] = useState<string[]>([]);
  const [inputValue, setInputValue] = useState('');
  const [disabled, setDisabled] = useState(false)
  const refSelect = useRef<SelectHandle>(null);
  const { image } = useTRPCClient()

  const debouncedFetchUser = useCallback(
    debounce(async (inputValue) => {
      if (!inputValue) {
        setOptions([])
        return;
      }
      const res = await image.searchTags.query({
        query: inputValue,
      });
      setOptions(res.map(item => ({
        label: renderLabel(item),
        value: item.content,
        extra: item,
      })));
      console.log('开始搜索',res);

    }, 500),
    []
  );

  useEffect(() => {
    if (!eq(value, internalValue)) {
      setInternalValue(value ? value?.split?.(',').filter(item => item.trim()) : []);
    }
  }, [value])

  const handleValueChange = (val: string[]) => {
    setInternalValue(val);

    onChange?.(val.join(','));
  }

  const renderLabel = (item: Tag) => {
    return <Space>
      <Typography.Text>{item.content}</Typography.Text>
      <Typography.Text type="primary">{item.translation}</Typography.Text>
    </Space>
  }

  const renderTag = (
    props: { value: any; label: React.ReactNode; closable: boolean; onClose: (event: any) => void }, 
    index: number, 
  ) => {
    const parsedValue = parseValue(props.value || '');
    
    return (
      <TagWithWeight
        key={index}
        value={parsedValue}
        onChange={({ text, weight }) => {
          const newValues = [...internalValue];
          console.log(parsedValue.text, parsedValue.weight);
          
          newValues[index] = `(${text}:${weight.toFixed(1)})`;
          handleValueChange(newValues);
        }}
        onRemove={props.onClose}
        onPopoverVisible={setDisabled}
      />
    );
  };

  return (
    <Select
      showSearch
      mode='multiple'
      ref={refSelect}
      options={options}
      dropdownMenuClassName={'prompt-input-dropdown'}
      filterOption={false}
      renderFormat={(option) => {
        return option?.children;
      }}
      triggerElement={
        <InputTag
          dragToSort
          allowClear  
          onKeyDown={(e) => {
            refSelect?.current?.hotkeyHandler(e);
          }}
          onChange={(value, reason) => {
            if (reason !== 'add' || !options?.length) {
              handleValueChange(value)
            }
          }}
          placeholder={`请输入中/英文关键字搜索，如："初音未来"或者"hatsune_miku"`}
          value={internalValue}
          inputValue={inputValue}
          renderTag={renderTag}
          onInputChange={val => {
            setInputValue(val)
            debouncedFetchUser(val)
          }}
          onPaste={(e) => {
            const copyValue = e.clipboardData.getData("text");
            if (copyValue) {
              handleValueChange(internalValue.concat(copyValue.split(',')));
              setTimeout(() => setInputValue(''), 0)
            }            
          }}
        />
      }
      disabled={disabled}
      // onSearch={debouncedFetchUser}
      onChange={(val) => {
        handleValueChange(val as string[]);
        setOptions([]);
        setInputValue('');
      }}
      trigger="click"
      value={internalValue}

    />
  );
}

export default PromptTagInput;
